<template>
  <div v-if="isTree">
    <treeselect
      :multiple="multiple"
      v-model="treeValue"
      :options="deptOptions"
      :show-count="true"
      :clearable="false"
      :value-consists-of="valueConsistsOf"
      :placeholder="placeholder"
      :limit="5"
    />
  </div>
  <div v-else>
    <el-select
      v-model="collegeId"
      placeholder="请选择学院"
      filterable
      clearable
      :disabled="disabled"
      :multiple="multiple"
    >
      <el-option
        v-for="dict in collegeList"
        :key="dict.id"
        :label="dict.collegeName"
        :value="dict.id"
      />
    </el-select>
  </div>
</template>

<script>
import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
import common from "@/api/collegebase/common";

export default {
  name: "CollegeSelector",
  props: {
    value: {
      required: true,
    },
    disabled: {
      type: Boolean,
      default: false,
    },
    multiple: {
      type: Boolean,
      default: false,
    },
    isTree: {
      type: Boolean,
      default: false,
    },
    valueConsistsOf: {
      type: String,
      default: "BRANCH_PRIORITY",
    },
    placeholder: {
      type: String,
      default: "请选择所属学院",
    }
  },
  model: {
    prop: "value",
    event: "change",
  },
  components: { Treeselect },
  data() {
    return {
      valueLoading: false,
      collegeList: [],
      departmentList: [],
      professionList: [],
      collegeId: null,
      treeValue: null,
      deptOptions: [],
      collegeIds: [], //0
      collegeAll: false,
      departmentIds: [], //1
      departmentAll: false,
      professionIds: [], //2
      professionAll: false,
      classesIds: [], //3
      treeObj: {}
    };
  },

  created() {
    this.getData();
  },

  watch: {
    collegeId(value) {
      console.log("collegeId", value);
      if (this.valueLoading) return;
      this.$emit("change", value);
    },
    treeValue(value) {
      console.log("treeValue", value);
      if (this.valueLoading || !value || !value.length) return;
      if (!this.isTree) {
        return this.$emit("change", value);
      }
      // 组装数据
      this.collegeIds = []; //0
      this.collegeAll = false;
      this.departmentIds = []; //1
      this.departmentAll = false;
      this.professionIds = []; //2
      this.professionAll = false;
      this.classesIds = []; //3
      this.treeObj = {};
      this.getCollegePermissionList([...this.deptOptions], value);
      if (this.collegeList.length == [...new Set(this.collegeIds)].length) {
        this.collegeAll = true;
      }
      if (this.departmentList.length == [...new Set(this.departmentIds)].length) {
        this.departmentAll = true;
      }
      if (this.professionList.length == [...new Set(this.professionIds)].length) {
        this.professionAll = true;
      }
      // console.log({
      //   collegeId: [...new Set(this.collegeIds)],
      //   collegeAll: this.collegeAll,
      //   departmentIds: [...new Set(this.departmentIds)],
      //   departmentAll: this.departmentAll,
      //   professionIds: [...new Set(this.professionIds)],
      //   professionAll: this.professionAll,
      //   classesIds: [...new Set(this.classesIds)],
      // });
      console.log(this.treeObj);
      this.$emit("change", value);
      this.$emit("onSuccess", this.treeObj);
      // this.$emit("onSuccess", {
      //   collegeId: [...new Set(this.collegeIds)],
      //   collegeAll: this.collegeAll,
      //   departmentIds: [...new Set(this.departmentIds)],
      //   departmentAll: this.departmentAll,
      //   professionIds: [...new Set(this.professionIds)],
      //   professionAll: this.professionAll,
      //   classesIds: [...new Set(this.classesIds)],
      // });
    },
    value: {
      immediate: true,
      handler(value) {
        this.valueLoading = true;
        if (this.isTree) {
          this.treeValue = value;
        } else {
          this.collegeId = value;
        }
        setTimeout(() => (this.valueLoading = false), 200);
      },
    },
  },
  methods: {
    //获取学院
    async getData() {
      const collegeList = await common.getCollegesList();
      this.collegeList = collegeList.data;
      this.deptOptions = collegeList.data.map((item) => {
        return {
          id: item.id,
          label: item.collegeName,
          children: this.getDepartmentsList(item.id),
        };
      });
    },
    //根据学院ID获取系部
    getDepartmentsList(collegeId) {
      let data = [];
      common.getDepartmentsList(collegeId).then((response) => {
        response.data.map((item) => {
          data.push({
            id: item.id,
            label: item.departmentName,
            children: this.getProfessionsList(item.id),
          });
        });
        this.departmentList.push(...response.data);
      });
      return data;
    },
    //根据系部ID获取专业
    getProfessionsList(departmentsId) {
      let data = [];
      common.getProfessionsList(departmentsId).then((response) => {
        response.data.map((item) => {
          data.push({
            id: item.id,
            label: item.professionName,
            children: this.getClassesList(item.id),
          });
        });
        this.professionList.push(...response.data);
      });
      return data;
    },
    //根据专业ID获取班级
    getClassesList(professionsId) {
      let data = [];
      common.getClassesList(professionsId).then((response) => {
        response.data.map((item) => {
          data.push({
            id: item.id,
            label: item.classesName,
          });
        });
      });
      return data;
    },

    // loadOptions({ action, parentNode, callback }) {
    //   if (action === "LOAD_CHILDREN_OPTIONS") {
    //     common[parentNode.method](parentNode.id).then((res) => {
    //       if (!res.code) {
    //         parentNode.children = res.data.map((item) => {
    //           if (item.departmentName != void 0) {
    //             return {
    //               method: "getProfessionsList",
    //               id: item.id,
    //               label: item.departmentName,
    //               children: null,
    //             };
    //           } else if (item.professionName != void 0) {
    //             return {
    //               method: "getClassesList",
    //               id: item.id,
    //               label: item.professionName,
    //               children: null,
    //             };
    //           } else if (item.classesName != void 0) {
    //             return {
    //               id: item.id,
    //               label: item.classesName,
    //             };
    //           }
    //         });
    //       } else {
    //         parentNode.children = [];
    //       }
    //     });
    //     callback();
    //   }
    // },
    // 学院
    getCollegePermissionList(array, selectIds) {
      //第一层
      let status = false;
      for (let item of array) {
        //选中了
        if (selectIds.includes(item.id)) {
          this.collegeIds.push(item.id);
          status = true;
        }
        if (status) {
          let data = { all: this.collegeIds.length == array.length ? true : false };
          data[item.id] = { all: true };
          if (item.children && item.children.length) {
            item.children.forEach((item1) => {   //处理系部
              data[item.id][item1.id] = { all: true };
              if (item1.children && item1.children.length) {
                item1.children.forEach((item2) => { //处理专业
                  data[item.id][item1.id][item2.id] = { all: true };
                  if (item2.children && item2.children.length) {
                    data[item.id][item1.id][item2.id]["class"] = [];
                    item2.children.forEach((item3) => {//班级
                      data[item.id][item1.id][item2.id]["class"].push(item3.id);

                    })
                  }
                })
              }
            })
          }

          this.treeObj = this.assiginObj(this.treeObj, data);
          status = false;
        }
        //有子集
        if (item.children && item.children.length) {
          //判断学院是否选中，选中就封装数据

          this.getDepartmentsPermissionList(item.children, selectIds, item.id);

        }
      }

    },
    //获取系部
    getDepartmentsPermissionList(array, selectIds, parentId) {
      let status = false;
      for (let item of array) {
        //选中了
        if (selectIds.includes(item.id)) {
          status = true;
          this.departmentIds.push(item.id);
        }
        if (status) {
          let data = { all: false };
          this.departmentIds.forEach((item4) => {
            data[parentId] = { all: false }; //学院
            data[parentId][item4] = { all: true };
            item.children.forEach((item2) => { //处理专业
              data[parentId][item4][item2.id] = { all: true };
              if (item2.children && item2.children.length) {
                data[parentId][item4][item2.id]["class"] = [];
                item2.children.forEach((item3) => {//班级
                  data[parentId][item4][item2.id]["class"].push(item3.id);

                })
              }
            })
          })
          this.treeObj = this.assiginObj(this.treeObj, data);
          status = false;
        }
        //有子集,
        if (item.children && item.children.length) {
          this.getProfessionsPermissionList(
            item.children,
            selectIds,
            item.id,
            parentId
          );
        }
      }
      // 到系部了，判断当前系部是否选中，选中上级需要
      if (status) {
        this.collegeIds.push(parentId);
      }
    },
    // 获取专业
    getProfessionsPermissionList(array, selectIds, parentId, collegeId) {
      let status = false;
      for (let item of array) {
        //选中了
        if (selectIds.includes(item.id)) {
          status = true;
          this.professionIds.push(item.id);
        }
        //处理专业,专业选中
        if (status) {
          let data = { all: false };
          data[collegeId] = { all: false }; //学院
          data[collegeId][parentId] = { all: false }; //系部
          data[collegeId][parentId][item.id] = { all: true }
          if (item.children && item.children.length) {
            data[collegeId][parentId][item.id]["class"] = [];
            item.children.forEach((item3) => {//班级
              data[collegeId][parentId][item.id]["class"].push(item3.id);
            })
          }
          this.treeObj = this.assiginObj(this.treeObj, data);
          status = false;
        }
        //有子集
        if (item.children && item.children.length) {
          this.getClassesPermissionList(
            item.children,
            selectIds,
            item.id,
            parentId,
            collegeId
          );
        }
      }
      // 到专业了，判断当前专业是否选中，选中上级需要
      if (status) {
        this.departmentIds.push(parentId);
      }
    },
    // 获取班级
    getClassesPermissionList(
      array,
      selectIds,
      parentId,
      departmentId,
      collegeId
    ) {
      let status = false;
      let data = { all: false };
      data[collegeId] = { all: false }; //学院
      data[collegeId][departmentId] = { all: false }; //系部
      data[collegeId][departmentId][parentId] = { all: false } //专业
      data[collegeId][departmentId][parentId]["class"] = [];
      for (let item of array) {
        //选中了
        if (selectIds.includes(item.id)) {
          status = true;
          this.classesIds.push(item.id);
          data[collegeId][departmentId][parentId]["class"].push(item.id)
        }
      }
      if (data[collegeId][departmentId][parentId] && data[collegeId][departmentId][parentId]["class"].length == array.length) {
        data[collegeId][departmentId][parentId]['all'] = true;
      }
      if (status) {
        this.treeObj = this.assiginObj(this.treeObj, data);
      }
      // 到班级了，判断当前班级是否选中，选中上级需要
      if (status) {
        this.professionIds.push(parentId);
        // 学院和系部是否已有，没，加上
        if (!this.collegeIds.includes(collegeId)) {
          this.collegeIds.push(collegeId);
          this.departmentIds.push(departmentId);
        }
      }
    },
    assiginObj(target = {}, sources = {}) {
      let obj = target;
      if (typeof target != 'object' || typeof sources != 'object') {
        return sources; // 如果其中一个不是对象 就返回sources
      }
      for (let key in sources) {
        // 如果target也存在 那就再次合并
        if (target.hasOwnProperty(key)) {
          obj[key] = this.assiginObj(target[key], sources[key]);
        } else {
          // 不存在就直接添加
          obj[key] = sources[key];
        }
      }
      return obj;
    }
  },
};
</script>
